{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 感知器算法实验\n",
    "分类器的算法的目的就是求出分类的权向量W。\n",
    "### 感知器算法的基本思想是：\n",
    "- 首先设置一个初始的权向量，然后用已知类别的模式样本去检验权向量的合理性，\n",
    "- 如果检验不合理，就对上一次的权向量进行修正，对修正后的权向量用已知类别的模式样本再去检验其合理性，知道满足合理性的要求为止。\n",
    "- 权值修正的方法一般采用梯度下降法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 原理\n",
    "设两类线性可分的模式$\\omega_1$, $\\omega_2$，判别函数为$d(X)=W^T*X$,\n",
    "其中$W=[w_1,w_2,...,w_d,w_{d+1}]$ ,$X=[x_1,x_2,...,x_d,x_{d+1}]$,都为增广列矩阵\n",
    "\n",
    "于是对于判别函数$d(X)有$如下性质：\n",
    "\n",
    "对于$\\omega_1$类样本，我们记标签$y=+1, w⋅x_i+b>0$,\n",
    "\n",
    "对于$\\omega_2$类样本，我们记标签$y=-1, w⋅x_i+b<0$,\n",
    "\n",
    "于是$d(X)=sign(w⋅x+b)$\n",
    "\n",
    "我们对样本进行规范化处理，将$d(X)$乘上对应的标签，即可得到判别函数的性质为：$d(X)=W^T*X > 0$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 感知器算法实现步骤：\n",
    "1. 给定初始值:给每个权向量赋任意值\n",
    "\n",
    "2. 输入训练样本进行训练\n",
    "\n",
    "3. 计算判别函数的判别值\n",
    "\n",
    "4. 修改权向量$W(k)$,修正规则如下：\n",
    "\n",
    "  - 若$d(Xi)\\leq0$, 则$W(k+1) = W(k)+ \\rho * y_i * X_i$\n",
    "  - $\\rho$为大于0的一常数(一般取$0<\\rho\\leq1$)\n",
    "  - 否则$W(k+1) = W(k)$\n",
    "\n",
    "5.当W对所有训练样本均稳定不变时，则结束。否则令$k=k+1$,返回步骤2."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实现Iris数据集分类(两类)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w= [-0.06500000000000003, 0.14400000000000002]\n",
      "准确率为:100.0%\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 700x500 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"实现Iris的分类\"\"\"\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "path = '../../data/Iris.data'\n",
    "df = pd.read_csv(path,header=None)\n",
    "x = df.loc[:99,[0,2]].values   #第一列和第三列的数据\n",
    "y = df.loc[:99,4].values\n",
    "y = np.where(y == 'Iris-setosa',-1,1)\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,random_state=200)\n",
    "\n",
    "def perceptron(Train_data, Label, exercise_times=50):\n",
    "    '''\n",
    "    训练感知器模型\n",
    "    :param Train_data:训练用的样本\n",
    "    :param Label:样本对应的标注\n",
    "    :param exercise_times:迭代次数\n",
    "    :return: W, b参数向量\n",
    "    '''\n",
    "    # 将数据转换成矩阵形式（在机器学习中因为通常都是向量的运算，转换成矩阵形式方便运算）\n",
    "    # 转换后的数据中每一个样本的向量都是横向的\n",
    "    dataMat = np.mat(Train_data)\n",
    "\n",
    "    # 将标签转换成矩阵，之后转置(.T为转置)。\n",
    "    # 转置是因为在运算中需要单独取label中的某一个元素，如果是1xN的矩阵的话，无法用label[i]的方式读取\n",
    "    # 对于只有1xN的label可以不转换成矩阵，直接label[i]即可，这里转换是为了格式上的统一\n",
    "    labelMat = np.mat(Label).T\n",
    "\n",
    "    # 获取数据矩阵的大小，为m*n\n",
    "    m, n = np.shape(dataMat)\n",
    "    # 创建初始权重w，b\n",
    "    w = np.zeros((1, np.shape(dataMat)[1]))\n",
    "    # 1代表一行，np.shape(datamat)[1]输出的是列数，也就是说W是一行，n列的矩阵\n",
    "    b = 0\n",
    "    # 初始学习率\n",
    "    learning_rate = 0.01\n",
    "\n",
    "    for k in range(exercise_times):\n",
    "        # 对于每一个样本进行梯度下降\n",
    "        for i in range(m):\n",
    "            # 获取当前样本的向量\n",
    "            xi = dataMat[i]\n",
    "            yi = labelMat[i]\n",
    "            if -1*yi * (w * xi.T + b) >= 0:\n",
    "                w = w + learning_rate * yi * xi\n",
    "                b = b + learning_rate * yi\n",
    "    return w.tolist(), b.tolist()\n",
    "\n",
    "\n",
    "def test(dataArr, labelArr, w, b):\n",
    "    '''\n",
    "    分类器的测试\n",
    "    :param dataArr: 样本的特征集\n",
    "    :param labelArr: 样本的标注\n",
    "    :param w: 权重向量\n",
    "    :param b: 偏置向量\n",
    "    :return: 准确率\n",
    "    '''\n",
    "    dataMat = np.mat(dataArr)\n",
    "    labelMat = np.mat(labelArr).T\n",
    "    m, n = np.shape(dataMat)\n",
    "    # 错误样本数计数\n",
    "    errorCnt = 0\n",
    "    # 遍历所有测试样本\n",
    "    for i in range(m):\n",
    "        xi = dataMat[i]\n",
    "        yi = labelMat[i]\n",
    "        # 获得运算结果\n",
    "        result = -1 * yi * (w * xi.T + b)\n",
    "        # 如果-yi(w*xi+b)>=0，说明该样本被误分类，错误样本数加一\n",
    "        if result >= 0: \n",
    "            errorCnt += 1\n",
    "    acc = 1 - (errorCnt / m)\n",
    "    return acc\n",
    "\n",
    "W,B = perceptron(x_train, y_train, exercise_times=2000)\n",
    "w = W[0]\n",
    "b = B[0]\n",
    "x_x = np.linspace(4,7,10)\n",
    "y_y = -(w[0] * x_x + b[0])/w[1]\n",
    "print(f\"w= {w}\")\n",
    "test_acc = test(x_test, y_test, W, B)\n",
    "print(f\"准确率为:{test_acc*100}%\")\n",
    "plt.figure(figsize=(7,5),dpi=100)\n",
    "plt.plot(x_x,y_y)\n",
    "plt.scatter(x[0:49,0],x[0:49,1],color='red',marker='o',label='-1')\n",
    "plt.scatter(x[50:100,0],x[50:100,1],color='blue',marker='x',label='1')\n",
    "plt.xlabel('length of petal')\n",
    "plt.ylabel('length of scape')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}